package com.example.oasysflow.controller;

import com.example.oasysflow.pojo.OAVO;
import com.example.oasysflow.service.flowservice.FlowService;
import com.example.oasysflow.service.impl.image.DefaultProcessDiagramGeneratorExt;
import com.nimbusds.jose.shaded.json.JSONArray;
import com.nimbusds.jose.shaded.json.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import liquibase.pro.packaged.A;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricDetail;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.idm.api.User;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @ClassName: LeaveController
 * @Description: 请假controller
 * @author: WangZe
 * @date: 2022/4/3 15:59
 */
@Slf4j
@Controller
@RequestMapping("leave")
@Api(tags = "请假")
@CrossOrigin(value = "http://localhost:3000")
public class LeaveController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private IdentityService identityService;

    @Autowired
    private FlowService flowService;

    /**
     * @author Wangze
     * @description 启动流程
     * @date 2020/8/26 17:36
     */
    @PostMapping(value = "startLeaveProcess")
    @ResponseBody
    @ApiOperation("启动流程")
    public OAVO startLeaveProcess(@ApiParam("发起人id") @RequestParam String staffId, @ApiParam("处理人id") @RequestParam String managerId) {
        log.info("发起人："+staffId + "  处理人: "+managerId);
        HashMap<String, Object> map = new HashMap<>();
        map.put("leaveTask", staffId);
        map.put("managerTask",managerId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Leave", map);
        log.info("创建process成功："+ processInstance.getId());
        OAVO oavo = new OAVO();
        oavo.setProcessId(processInstance.getId());
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(staffId).orderByTaskCreateTime().desc().list();
        for (Task task : tasks) {
            oavo.setTaskId(task.getId());
        }
        return oavo;
    }

    /**
     * @param taskId
     * @author Wangze
     * @description 批准
     * @date 2020/8/27 14:30
     */
    @PostMapping(value = "applyTask")
    @ResponseBody
    @ApiOperation("批准、驳回")
    public String applyTask(@RequestParam("taskId") String taskId ,@RequestParam("checkResult") String checkResult) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new RuntimeException("流程不存在");
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("checkResult", checkResult);
        taskService.complete(taskId, map);
        return "申请审核状态已更新："+checkResult;
    }

    /**
     * @author Wangze
     * @description 查看用户发起的流程
     * @date 2020/8/27 14:30
     */
    @PostMapping(value = "getProcessList")
    @ResponseBody
    @ApiOperation("查看用户发起的流程")
    public List<ProcessInstance> getProcessList(@RequestParam("userId") String userId) {
        List<ProcessInstance> processInstances = runtimeService.createProcessInstanceQuery().startedBy(userId).list();
        return processInstances;
    }



    /**
     * @author Wangze
     * @description 生成流程图
     * @date 2020/8/27 14:29
     */
    @GetMapping(value = "createProcessDiagramPic")
    @ApiOperation("生成流程图")
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) {
        /**
         * 获得当前活动的节点
         */
        String processDefinitionId = "";
        if (this.isFinished(processId)) {// 如果流程已经结束，则得到结束节点
            HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();

            processDefinitionId=pi.getProcessDefinitionId();
        } else {// 如果流程没有结束，则取当前活动节点
            // 根据流程实例ID获得当前处于活动状态的ActivityId合集
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
            processDefinitionId=pi.getProcessDefinitionId();
        }
        List<String> highLightedActivitis = new ArrayList<String>();
        /**
         * 获得活动的节点
         */
        List<HistoricActivityInstance> highLightedActivitList =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
        //高亮节点
        for(HistoricActivityInstance tempActivity : highLightedActivitList){
            String activityId = tempActivity.getActivityId();
            highLightedActivitis.add(activityId);
        }
        List<String>  highLightedflows = new ArrayList<>();
        //高亮线
        for(HistoricActivityInstance tempActivity : highLightedActivitList){
            if("sequenceFlow".equals(tempActivity.getActivityType())){
                highLightedflows.add(tempActivity.getActivityId());
            }
        }
        //获取流程图
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        // ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        //获取自定义图片生成器
        ProcessDiagramGenerator diagramGenerator = new DefaultProcessDiagramGeneratorExt();
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "bmp", highLightedActivitis, highLightedflows, engconf.getActivityFontName(),
                engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int legth = 0;
        try {
            out = httpServletResponse.getOutputStream();
            while ((legth = in.read(buf)) != -1) {
                out.write(buf, 0, legth);
            }
        } catch (IOException e) {
            throw new RuntimeException("IO异常");
        } finally {
            IOUtils.closeQuietly(out);
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * @author Wangze
     * @description 流程是否结束
     * @date 2020/8/27 14:29
     */
    public boolean isFinished(String processId) {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
        if (pi == null) {
            return true;
        }
        return false;
    }

    /**
     * @author Wangze
     * @description 新增User
     * @date 2020/8/27 14:29
     */
    @ResponseBody
    @PostMapping(value = "addUser")
    @ApiOperation("新增User")
    public String addUser(@ApiParam("userId") @RequestParam String userId) {
        log.info("新增User：" + userId);
        User user = flowService.addUser(userId);
        return "新增User成功~" + user.getId();
    }










}
